Sensor Fusion for Kinetis MCUs (ISSDK/KSDK version)
debug.h File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void ApplyPerturbation (SensorFusionGlobals *sfg)
 

Detailed Description

The ApplyPerturbation function applies a user-specified step function to prior fusion results which is then "released" in the next fusion cycle. When used in conjustion with the NXP Sensor Fusion Toolbox, this provides a visual indication of the dynamic behavior of the library.

Definition in file debug.h.

Function Documentation

void ApplyPerturbation ( SensorFusionGlobals sfg)

The ApplyPerturbation function applies a user-specified step function to prior fusion results which is then "released" in the next fusion cycle. When used in conjustion with the NXP Sensor Fusion Toolbox, this provides a visual indication of the dynamic behavior of the library. This function is normally involved via the "sfg." global pointer.

Definition at line 53 of file debug.c.

54 {
55 #ifdef INCLUDE_DEBUG_FUNCTIONS
56  // volatile keyword used to force compiler not to optimize out these
57  // variables. this does unfortunately result in a couple of warnings (which
58  // can be ignored) farther down in this code.
59  volatile static uint16_t iTestProgress; ///< Perturbation test status
60  volatile static uint16_t iTestDelay = 0; ///< Measured delay
61  volatile static uint16_t iTestAngle = 0; ///< Integer Residual angle associated with measured delay
62  volatile float angle=0.0f; ///< Float Residual angle associated with measured delay
63  volatile static float threshold=0;
64  static Quaternion StartingQ = {
65  .q0 = 1.0,
66  .q1 = 0.0,
67  .q2 = 0.0,
68  .q3 = 0.0
69  };
70  Quaternion CurrentQ = {
71  .q0 = 1.0,
72  .q1 = 0.0,
73  .q2 = 0.0,
74  .q3 = 0.0
75  };
76  // cache local copies of control flags so we don't have to keep dereferencing pointers below
77  quaternion_type quaternionPacketType;
78  quaternionPacketType = sfg->pControlSubsystem->QuaternionPacketType;
79 
80  Quaternion ftmpq; // scratch quaternion
81 
82  // calculate the test perturbation
83  switch (sfg->iPerturbation)
84  {
85  case 1: // 180 degrees about X
86  ftmpq.q0 = 0.0F;
87  ftmpq.q1 = 1.0F;
88  ftmpq.q2 = 0.0F;
89  ftmpq.q3 = 0.0F;
90  threshold = 90.0;
91  break;
92 
93  case 2: // 180 degrees about Y
94  ftmpq.q0 = 0.0F;
95  ftmpq.q1 = 0.0F;
96  ftmpq.q2 = 1.0F;
97  ftmpq.q3 = 0.0F;
98  threshold = 90.0;
99  break;
100 
101  case 3: // 180 degrees about Z
102  ftmpq.q0 = 0.0F;
103  ftmpq.q1 = 0.0F;
104  ftmpq.q2 = 0.0F;
105  ftmpq.q3 = 1.0F;
106  threshold = 90.0;
107  break;
108 
109  case 4: // -90 degrees about X
110  ftmpq.q0 = ONEOVERSQRT2;
111  ftmpq.q1 = -ONEOVERSQRT2;
112  ftmpq.q2 = 0.0F;
113  ftmpq.q3 = 0.0F;
114  threshold = 45.0;
115  break;
116 
117  case 5: // +90 degrees about X
118  ftmpq.q0 = ONEOVERSQRT2;
119  ftmpq.q1 = ONEOVERSQRT2;
120  ftmpq.q2 = 0.0F;
121  ftmpq.q3 = 0.0F;
122  threshold = 45.0;
123  break;
124 
125  case 6: // -90 degrees about Y
126  ftmpq.q0 = ONEOVERSQRT2;
127  ftmpq.q1 = 0.0F;
128  ftmpq.q2 = -ONEOVERSQRT2;
129  ftmpq.q3 = 0.0F;
130  threshold = 45.0;
131  break;
132 
133  case 7: // +90 degrees about Y
134  ftmpq.q0 = ONEOVERSQRT2;
135  ftmpq.q1 = 0.0F;
136  ftmpq.q2 = ONEOVERSQRT2;
137  ftmpq.q3 = 0.0F;
138  threshold = 45.0;
139  break;
140 
141  case 8: // -90 degrees about Z
142  ftmpq.q0 = ONEOVERSQRT2;
143  ftmpq.q1 = 0.0F;
144  ftmpq.q2 = 0.0F;
145  ftmpq.q3 = -ONEOVERSQRT2;
146  threshold = 45.0;
147  break;
148 
149  case 9: // +90 degrees about Z
150  ftmpq.q0 = ONEOVERSQRT2;
151  ftmpq.q1 = 0.0F;
152  ftmpq.q2 = 0.0F;
153  ftmpq.q3 = ONEOVERSQRT2;
154  threshold = 45.0;
155  break;
156 
157  default: // No rotation
158  ftmpq.q0 = 1.0F;
159  ftmpq.q1 = 0.0F;
160  ftmpq.q2 = 0.0F;
161  ftmpq.q3 = 0.0F;
162  break;
163  }
164 
165  switch (quaternionPacketType) {
166 #if F_3DOF_G_BASIC
167  case (Q3):
168  CurrentQ = sfg->SV_3DOF_G_BASIC.fLPq;
169  qAeqAxB(&(sfg->SV_3DOF_G_BASIC.fLPq), &ftmpq);
170  break;
171 #endif
172 #if F_3DOF_B_BASIC
173  case (Q3M):
174  CurrentQ = sfg->SV_3DOF_B_BASIC.fLPq;
175  qAeqAxB(&(sfg->SV_3DOF_B_BASIC.fLPq), &ftmpq);
176  break;
177 #endif
178 #if F_3DOF_Y_BASIC
179  case (Q3G):
180  CurrentQ = sfg->SV_3DOF_Y_BASIC.fq;
181  qAeqAxB(&(sfg->SV_3DOF_Y_BASIC.fq), &ftmpq);
182  break;
183 #endif
184 #if F_6DOF_GB_BASIC
185  case (Q6MA):
186  CurrentQ = sfg->SV_6DOF_GB_BASIC.fLPq;
187  qAeqAxB(&(sfg->SV_6DOF_GB_BASIC.fLPq), &ftmpq);
188  break;
189 #endif
190 #if F_6DOF_GY_KALMAN
191  case (Q6AG):
192  CurrentQ = sfg->SV_6DOF_GY_KALMAN.fqPl;
193  qAeqAxB(&(sfg->SV_6DOF_GY_KALMAN.fqPl), &ftmpq);
194  break;
195 #endif
196 #if F_9DOF_GBY_KALMAN
197  case (Q9):
198  CurrentQ = sfg->SV_9DOF_GBY_KALMAN.fqPl;
199  qAeqAxB(&(sfg->SV_9DOF_GBY_KALMAN.fqPl), &ftmpq);
200  break;
201 #endif
202  default:
203  CurrentQ.q0 = 1.0;
204  CurrentQ.q1 = 0.0;
205  CurrentQ.q2 = 0.0;
206  CurrentQ.q3 = 0.0;
207  break;
208  }
209 
210  // Begin of code for white-box testing - requires IAR debugger
211  switch (iTestProgress) {
212  case 0: // no test in progress, check to see if we should start one
213  if (sfg->iPerturbation>0) {
214  // Start Test
215  iTestProgress = 1;
216  sfg->iPerturbation = 0;
217  iTestDelay = 0;
218  iTestAngle = 0;
219  // We'll need the complex conjugate of the starting quaternion
220  StartingQ.q0 = CurrentQ.q0;
221  StartingQ.q1 = -1 * CurrentQ.q1;
222  StartingQ.q2 = -1 * CurrentQ.q2;
223  StartingQ.q3 = -1 * CurrentQ.q3;
224  }
225  break;
226  default: // Test in progress, check to see if trigger reached
227  iTestDelay += 1;
228  qAeqAxB(&CurrentQ, &StartingQ);
229  angle = 2 * F180OVERPI * acos(CurrentQ.q0);
230  angle = fmod(fabs(angle), 180.0);
231  iTestAngle = (uint16_t) (10 * angle);
232  // In IAR, you can use a Log breakpoint to monitor "return to stationary pose".
233  // Use the following expression in the Message field and check the
234  // checkbox for C-Spy macro. Then Click any of the "Test" buttons
235  // in the Sensor Fusion Toolbox and monitor the results in the Messages window.
236  //"Delay=", iTestDelay:%d, " Angle=",iTestAngle:%d
237  if (angle<threshold) iTestProgress=2; // triggered
238  if (angle < (0.2 * threshold)) iTestProgress=0; // test is done
239  if (iTestDelay>100) iTestProgress=0; // abort test
240  break;
241  }
242  // End of code for white-box testing
243 #endif
244 }
enum quaternion quaternion_type
the quaternion type to be transmitted
Quaternion derived from full 9-axis sensor fusion.
Definition: sensor_fusion.h:70
#define ONEOVERSQRT2
1/sqrt(2)
float q0
scalar component
Definition: orientation.h:39
Quaternion derived from 3-axis mag only (auto compass algorithm)
Definition: sensor_fusion.h:66
float q3
z vector component
Definition: orientation.h:42
Quaternion derived from 3-axis gyro only (rotation)
Definition: sensor_fusion.h:67
Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
Definition: sensor_fusion.h:68
Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
Definition: sensor_fusion.h:69
struct ControlSubsystem * pControlSubsystem
quaternion structure definition
Definition: orientation.h:37
#define F180OVERPI
radians to degrees conversion = 180 / pi
Quaternion derived from 3-axis accel (tilt)
Definition: sensor_fusion.h:65
float q2
y vector component
Definition: orientation.h:41
void qAeqAxB(Quaternion *pqA, const Quaternion *pqB)
function compute the quaternion product qA = qA * qB
Definition: orientation.c:969
float q1
x vector component
Definition: orientation.h:40
volatile uint8_t iPerturbation
test perturbation to be applied
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
Definition: control.h:66

+ Here is the call graph for this function: